/**********************************************************************************
**
** Copyright (C) 2009 Jostein Bratlie
** Contact: jostein.bratlie@gmail.com | http://bratlie.info | http://episteme.hin.no
**
** This file is part of GMQtExt, a GMlib and Qt extension library
**
** GMQtExt is free software: you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** GMQtExt is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with GMQtExt.  If not, see <http://www.gnu.org/licenses/>.
**
**********************************************************************************/



// Header
#include "propertymanager.h"

// GMlib
#include <gmPoint2D>

namespace GMQtExt {

  SurfacePlotPropertyManager::SurfacePlotPropertyManager( QObject* parent )
    : QtAbstractPropertyManager( parent ) {

    _pm = new QtVariantPropertyManager;
  }

  SurfacePlotPropertyManager::~SurfacePlotPropertyManager() {

    delete _pm;
  }

  GMlib::Point<int, 2> SurfacePlotPropertyManager::getNoDerivatives( const QtProperty *property ) const {

    if( !_property_to_data.contains( property ) )
      return GMlib::Point2D<int>( 0, 0 );

    return _property_to_data[property].no_derivatives;
  }


  GMlib::Point<int, 2> SurfacePlotPropertyManager::getNoSamples( const QtProperty *property ) const {

    if( !_property_to_data.contains( property ) )
      return GMlib::Point2D<int>( 0, 0 );

    return _property_to_data[property].no_samples;
  }

  QtVariantPropertyManager* SurfacePlotPropertyManager::getSubVariantPropertyManager() {

    return _pm;
  }

  void SurfacePlotPropertyManager::setNoDerivatives(QtProperty *property, const GMlib::Point<int, 2>& no_derivatives) {

    if( !_property_to_data.contains( property ) )
      return;

    Data d = _property_to_data[property];
    if(d.no_derivatives == no_derivatives)
      return;

    d.no_derivatives = no_derivatives;

    if(d.der_u)
      d.der_u->setValue( no_derivatives(0) );

    if(d.der_v)
      d.der_v->setValue( no_derivatives(1) );

    _property_to_data[property] = d;

    emit propertyChanged(property);
    emit valueChanged( property, d.no_samples, d.no_derivatives );

  }

  void SurfacePlotPropertyManager::setNoSamples(QtProperty *property, const GMlib::Point<int, 2>& no_samples) {

    if( !_property_to_data.contains( property ) )
      return;

    Data d = _property_to_data[property];
    if(d.no_samples == no_samples)
      return;

    d.no_samples = no_samples;

    if(d.samp_u)
      d.samp_u->setValue( no_samples(0) );

    if(d.samp_v)
      d.samp_v->setValue( no_samples(1) );

    _property_to_data[property] = d;

    emit propertyChanged(property);
    emit valueChanged( property, d.no_samples, d.no_derivatives );

  }

  void SurfacePlotPropertyManager::slotForcedReplot() {

    emit signForcedReplot();
  }

  QString SurfacePlotPropertyManager::valueText(const QtProperty *property) const {

    GMlib::Point<int,2> no_der = getNoDerivatives( property );
    GMlib::Point<int,2> no_samples = getNoSamples( property );

    return QString("u/v: %1/%2 [%3/%4]")
        .arg( no_samples(0) ).arg( no_samples(1) )
        .arg( no_der(0) ).arg( no_der(1) );
  }

  void SurfacePlotPropertyManager::initializeProperty( QtProperty *property ) {

    Data d;
    d.no_derivatives = GMlib::Point2D<int>( 0, 0 );
    d.no_samples = GMlib::Point2D<int>( 0, 0 );

    d.samp_u = _pm->addProperty( QVariant::Int );
    d.samp_u->setPropertyName( tr( "Samples U" ) );
    property->addSubProperty( d.samp_u );
    _sampu_to_property[d.samp_u] = property;

    d.samp_v = _pm->addProperty( QVariant::Int );
    d.samp_v->setPropertyName( tr( "Samples V" ) );
    property->addSubProperty( d.samp_v );
    _sampv_to_property[d.samp_v] = property;

    d.der_u = _pm->addProperty( QVariant::Int );
    d.der_u->setPropertyName( tr( "Derivatives U" ) );
    property->addSubProperty( d.der_u );
    _deru_to_property[d.der_u] = property;

    d.der_v = _pm->addProperty( QVariant::Int );
    d.der_v->setPropertyName( tr( "Derivatives V" ) );
    property->addSubProperty( d.der_v );
    _derv_to_property[d.der_v] = property;

    _property_to_data[property] = d;
  }

  void SurfacePlotPropertyManager::uninitializeProperty( QtProperty *property ) {

    if( _property_to_data.contains(property) ) {

      Data d = _property_to_data[property];

      if( d.samp_u )
        _sampu_to_property.remove( d.samp_u );
      if( d.samp_v )
        _sampv_to_property.remove( d.samp_v );

      if( d.der_u )
        _deru_to_property.remove( d.der_u );
      if( d.der_v )
        _derv_to_property.remove( d.der_v );

      _property_to_data.remove( property );
    }
  }


} // END namespace GMQtExt
